Imports Microsoft.VisualBasic
Imports System
Imports System.Collections.Generic
Imports System.Text
Imports System.Text.RegularExpressions
Imports System.ComponentModel
Imports System.Globalization
Imports C4F.DevKit.WebServices.Datasets

Namespace C4F.DevKit.WebServices
	''' <summary>
	''' Represents search friends functionality on Myspace.com
	''' </summary>
	<ToolboxItem(True)> _
	Public Class MySpace
		Inherits C4FWebServicesBase
		#Region "Private members"

		''' <summary>
		''' Base url
		''' </summary>
        Private Shared baseUrl As String = My.Resources.MySpaceBaseUrl

		#End Region

		#Region "Public functions"

		''' <summary>
		''' The method searches for friends matching the parameter 'name'
		''' </summary>
		''' <param name="name">Name of the users to be searched</param>
		''' <returns>A list of friends matching the criteria</returns>
		Public Function SearchFriends(ByVal name As String) As List(Of MySpaceUser)
			Dim requestUrl As String = MySpace.GetQueryString(name)

			' Get MySpace response
			Dim responseData As String = MyBase.GetQueryResponse(requestUrl)

			Return MySpace.ParseResponseHtml(responseData)
		End Function

		''' <summary>
		''' The method searches for friends matching the parameter 'name'
		''' </summary>
		''' <param name="name">Name of the users to be searched</param>
		''' <returns>Dataset containing list of friends matching the criteria</returns>
		Public Function SearchFriends_DS(ByVal name As String) As DS_MySpace
			Dim friends As List(Of MySpaceUser) = SearchFriends(name)
			Dim dataset As DS_MySpace = New DS_MySpace()
			For Each [friend] As MySpaceUser In friends
				Dim userDetailsRow As DS_MySpace.UserDetailsRow = dataset.UserDetails.AddUserDetailsRow([friend].UserDetails.Headline, [friend].UserDetails.Orientation, [friend].UserDetails.HereFor, [friend].UserDetails.Gender, [friend].UserDetails.Age, [friend].UserDetails.Location)

				dataset.MySpaceUser.AddMySpaceUserRow([friend].Id, [friend].Name, [friend].ImageUrl, [friend].LastProfileUpdate, userDetailsRow)
			Next [friend]
			Return dataset
		End Function
		#End Region

		#Region "Private functions"
		''' <summary>
		''' The method Prepares the query string based on parameters
		''' </summary>
		''' <param name="name">Name of the users to be searched</param>
		''' <returns>Request Url</returns>
		Private Shared Function GetQueryString(ByVal name As String) As String
			Dim queryBuilder As StringBuilder = New StringBuilder(MySpace.baseUrl)

			queryBuilder.Append("?fuseaction=find.search&searchType=network&interesttype=&country=&searchBy=First&f_first_name=")
			queryBuilder.Append(name)
			queryBuilder.Append("&SearchBoxID=FindAFriend")

			Return queryBuilder.ToString()
		End Function

		''' <summary>
		''' Parses the response data and extracts the photo items
		''' </summary>
		''' <param name="responseData">Response data</param>
		''' <returns>Photo item list</returns>
		Private Shared Function ParseResponseHtml(ByVal responseData As String) As List(Of MySpaceUser)
			Dim matchingUsers As List(Of MySpaceUser) = New List(Of MySpaceUser)()
			' search for friendresults table in page content
			Dim friendResultExpression As String = "id=("")?friendresults("")?"
			Dim friendResultTableMatch As Match = Regex.Match(responseData, friendResultExpression, RegexOptions.IgnoreCase Or RegexOptions.IgnorePatternWhitespace)
			' no match found. no search results were found for input name
			If friendResultTableMatch.Success = False Then
				Return matchingUsers
			End If
			' find second findpaging entry in response data
			Dim pagingRegex As Regex = New Regex("class=("")?findpaging("")?")
			Dim pagingEndMatch As Match = pagingRegex.Match(responseData, friendResultTableMatch.Index)

			' our matching results will lie between these two indices in repsonse data
			Dim tempData As String = responseData.Substring(friendResultTableMatch.Index, pagingEndMatch.Index - friendResultTableMatch.Index)

			Dim rowStartIndex As Integer = tempData.IndexOf("<tr>")

			Do
				Dim rowEndIndex As Integer = tempData.IndexOf("</tr>")
				Dim rowString As String = tempData.Substring(rowStartIndex, rowEndIndex - rowStartIndex)

				Dim mySpaceUser As MySpaceUser = New MySpaceUser()
				mySpaceUser.UserDetails = New UserDetails()

				Dim profileURLExpression As String = "(http://profile.myspace.com/index.cfm[?]fuseaction=user.viewprofile&friendID=)([0-9]*)"

				Dim profileURLMatch As Match = Regex.Match(rowString, profileURLExpression, RegexOptions.IgnoreCase)
				mySpaceUser.Id = Convert.ToInt32(profileURLMatch.Value.Substring("http://profile.myspace.com/index.cfm?fuseaction=user.viewprofile&friendID=".Length), CultureInfo.InvariantCulture)

				If rowString.IndexOf("no_pic.gif") = -1 Then
					' set pic url
					Dim imageExpression As String = "(src=)("")?"
					Dim imageMatch As Match = Regex.Match(rowString, imageExpression, RegexOptions.IgnoreCase Or RegexOptions.IgnorePatternWhitespace)
					Dim tempURL As String = rowString.Substring(imageMatch.Index + imageMatch.Length, rowString.IndexOf("/>") - imageMatch.Index - imageMatch.Length)
					mySpaceUser.ImageUrl = tempURL.Replace("""", String.Empty).Trim()
				End If

				' remove first profile url match
				rowString = rowString.Substring(profileURLMatch.Index + profileURLMatch.Length)
				mySpaceUser.Name = rowString.Substring(0, rowString.IndexOf("</a>", StringComparison.InvariantCultureIgnoreCase))
				mySpaceUser.Name = mySpaceUser.Name.Substring(mySpaceUser.Name.LastIndexOf(">") + 1).Trim()
				' find profile url in remaining content. this match contains user name
				profileURLMatch = Regex.Match(rowString, profileURLExpression & """?[>]")
				'  rowString = rowString.Substring(profileURLMatch.Index + profileURLMatch.Length);

                ' set headline
                mySpaceUser.UserDetails.Headline = rowString.Substring(rowString.IndexOf("</strong>") + "</strong>".Length, rowString.IndexOf("<br /><strong>") - rowString.IndexOf("</strong>") - "</strong>".Length).Trim()
				If mySpaceUser.UserDetails.Headline = """""" Then
					mySpaceUser.UserDetails.Headline = String.Empty
				End If
				mySpaceUser.UserDetails.Headline = mySpaceUser.UserDetails.Headline.Replace("""", String.Empty)

                rowString = rowString.Substring(rowString.IndexOf("<br /><strong>") + "<br /><strong>".Length)
				' set orientation
                mySpaceUser.UserDetails.Orientation = rowString.Substring(rowString.IndexOf("</strong>") + "</strong>".Length, rowString.IndexOf("<br /><strong>") - rowString.IndexOf("</strong>") - "</strong>".Length).Trim()

                rowString = rowString.Substring(rowString.IndexOf("<br /><strong>") + "<br /><strong>".Length)
				' set "here for"
                mySpaceUser.UserDetails.HereFor = rowString.Substring(rowString.IndexOf("</strong>") + "</strong>".Length, rowString.IndexOf("<br /><strong>") - rowString.IndexOf("</strong>") - "</strong>".Length).Trim()

                rowString = rowString.Substring(rowString.IndexOf("<br /><strong>") + "<br /><strong>".Length)
				' set gender
                mySpaceUser.UserDetails.Gender = rowString.Substring(rowString.IndexOf("</strong>") + "</strong>".Length, rowString.IndexOf("<br /><strong>") - rowString.IndexOf("</strong>") - "</strong>".Length).Trim()

                rowString = rowString.Substring(rowString.IndexOf("<br /><strong>") + "<br /><strong>".Length)
				' set age

                mySpaceUser.UserDetails.Age = Convert.ToInt32(rowString.Substring(rowString.IndexOf("</strong>") + "</strong>".Length, rowString.IndexOf("<br /><strong>") - rowString.IndexOf("</strong>") - "</strong>".Length).Trim(), CultureInfo.InvariantCulture)

                rowString = rowString.Substring(rowString.IndexOf("<br /><strong>") + "<br /><strong>".Length)
				' set location
                mySpaceUser.UserDetails.Location = rowString.Substring(rowString.IndexOf("</strong>") + "</strong>".Length, rowString.IndexOf("<br /><strong>") - rowString.IndexOf("</strong>") - "</strong>".Length).Trim()

                rowString = rowString.Substring(rowString.IndexOf("<br /><strong>") + "<br /><strong>".Length)
                rowString = rowString.Substring(rowString.IndexOf("</strong>") + "</strong>".Length).Trim()


				mySpaceUser.LastProfileUpdate = DateTime.Parse(rowString.Substring(0, rowString.IndexOf("<"c)), CultureInfo.InvariantCulture)

				' add this user to matching users list
				matchingUsers.Add(mySpaceUser)

				' remove this row's data from content string
                tempData = tempData.Substring(rowEndIndex + "</tr>".Length)
				rowStartIndex = tempData.IndexOf("<tr>")
			Loop While rowStartIndex > -1
			Return matchingUsers
		End Function
		#End Region
	End Class

	''' <summary>
	''' Represented a user on Myspace.com
	''' </summary>
	Public Class MySpaceUser
		#Region "Private Members"
		''' <summary>
		''' Id of the user
		''' </summary>
		Private id_Renamed As Integer
		''' <summary>
		''' Name of the user
		''' </summary>
		Private name_Renamed As String
		''' <summary>
		''' Url of user's image
		''' </summary>
		Private imageUrl_Renamed As String
		''' <summary>
		''' Date and time when user's profile last updated
		''' </summary>
		Private lastProfileUpdate_Renamed As DateTime
		''' <summary>
		''' User details
		''' </summary>
		Private userDetails_Renamed As UserDetails
		#End Region

		#Region "Public Properties"
		''' <summary>
		''' Gets/Sets User's Id
		''' </summary>
		Public Property Id() As Integer
			Get
				Return Me.id_Renamed
			End Get
			Set(ByVal value As Integer)
				Me.id_Renamed = value
			End Set
		End Property
		''' <summary>
		''' Gets/Sets User's Name
		''' </summary>
		Public Property Name() As String
			Get
				Return Me.name_Renamed
			End Get
			Set(ByVal value As String)
				Me.name_Renamed = value
			End Set
		End Property
		''' <summary>
		''' Gets/Sets User's image Url
		''' </summary>
		Public Property ImageUrl() As String
			Get
				Return Me.imageUrl_Renamed
			End Get
			Set(ByVal value As String)
				Me.imageUrl_Renamed = value
			End Set
		End Property
		''' <summary>
		''' Gets/Sets DateTime when user had last updated the profile
		''' </summary>
		Public Property LastProfileUpdate() As DateTime
			Get
				Return Me.lastProfileUpdate_Renamed
			End Get
			Set(ByVal value As DateTime)
				Me.lastProfileUpdate_Renamed = value
			End Set
		End Property
		''' <summary>
		''' Gets/Sets User details
		''' </summary>
		Public Property UserDetails() As UserDetails
			Get
				Return Me.userDetails_Renamed
			End Get
			Set(ByVal value As UserDetails)
				Me.userDetails_Renamed = value
			End Set
		End Property
		#End Region
	End Class

	''' <summary>
	''' Represents the user details
	''' </summary>
	Public Class UserDetails
		#Region "Private Members"
		''' <summary>
		''' User's headline
		''' </summary>
		Private headline_Renamed As String
		''' <summary>
		''' User's Orientation
		''' </summary>
		Private orientation_Renamed As String
		''' <summary>
		''' Puspose of user to be on Myspace
		''' </summary>
		Private hereFor_Renamed As String
		''' <summary>
		''' Gender of the user
		''' </summary>
		Private gender_Renamed As String
		''' <summary>
		''' User's Age
		''' </summary>
		Private age_Renamed As Integer
		''' <summary>
		''' User's lacation
		''' </summary>
		Private location_Renamed As String
		#End Region

		#Region "Public Properties"
		''' <summary>
		''' Gets/Sets User's headline
		''' </summary>
		Public Property Headline() As String
			Get
				Return Me.headline_Renamed
			End Get
			Set(ByVal value As String)
				Me.headline_Renamed = value
			End Set
		End Property
		''' <summary>
		''' Gets/Sets User's Orientation informatation
		''' </summary>
		Public Property Orientation() As String
			Get
				Return Me.orientation_Renamed
			End Get
			Set(ByVal value As String)
				Me.orientation_Renamed = value
			End Set
		End Property
		''' <summary>
		''' Gets/Sets User's purpose of to be on Myspace
		''' </summary>
		Public Property HereFor() As String
			Get
				Return Me.hereFor_Renamed
			End Get
			Set(ByVal value As String)
				Me.hereFor_Renamed = value
			End Set
		End Property
		''' <summary>
		''' Gets/Sets User's gender
		''' </summary>
		Public Property Gender() As String
			Get
				Return Me.gender_Renamed
			End Get
			Set(ByVal value As String)
				Me.gender_Renamed = value
			End Set
		End Property
		''' <summary>
		''' Gets/Sets User's Age
		''' </summary>
		Public Property Age() As Integer
			Get
				Return Me.age_Renamed
			End Get
			Set(ByVal value As Integer)
				Me.age_Renamed = value
			End Set
		End Property
		''' <summary>
		''' Gets/Sets User's Location
		''' </summary>
		Public Property Location() As String
			Get
				Return Me.location_Renamed
			End Get
			Set(ByVal value As String)
				Me.location_Renamed = value
			End Set
		End Property

		#End Region
	End Class
End Namespace